﻿using Furion.DependencyInjection;
using Furion.JsonSerialization;
using Microsoft.Extensions.Caching.Distributed;
using System.Text;

namespace GMS.NET.Core.Provider.CacheProvider
{
    /// <summary>
    /// 
    /// </summary>
    public class SqlServer : ICachingService, ISingleton
    {
        private readonly IDistributedCache _distributedCache;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="distributedCache"></param>
        public SqlServer(IDistributedCache distributedCache)
        {
            this._distributedCache = distributedCache;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> AnyAsync(string key)
        {
            try
            {
                var getValue=await _distributedCache.GetStringAsync(key);
                return !string.IsNullOrWhiteSpace(getValue);
            }
            catch (Exception) { return false; }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<T> GetAsync<T>(string key)
        {
            try
            {
                var result = await _distributedCache.GetAsync(key);
                if (result != null)
                {
                    return JSON.Deserialize<T>(Encoding.UTF8.GetString(result));
                }
                return default(T)!;
            }
            catch (Exception)  { return default(T)!; }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> GetStringAsync(string key)
        {
            try
            {
                var result =await _distributedCache.GetStringAsync(key);
                return result!;
            }
            catch (Exception){   return string.Empty;   }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        public void Remove(string key)
        {
            try
            {
                _distributedCache.Remove(key);
            }
            catch (Exception)  {  }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="absoluteExpirationRelativeToNow"></param>
        public void Set<T>(string key, T value, TimeSpan absoluteExpirationRelativeToNow)
        {
            try
            {
                var options = new DistributedCacheEntryOptions()
                .SetSlidingExpiration(absoluteExpirationRelativeToNow);
                byte[] result = Encoding.UTF8.GetBytes(JSON.Serialize(value));
                _distributedCache.Set(key, result, options);
            }
            catch (Exception){}
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="absoluteExpirationRelativeToNow"></param>
        /// <returns></returns>
        public async Task SetAsync<T>(string key, T value, TimeSpan absoluteExpirationRelativeToNow)
        {
            try
            {
                var options = new DistributedCacheEntryOptions()
                .SetSlidingExpiration(absoluteExpirationRelativeToNow);
                byte[] result = Encoding.UTF8.GetBytes(JSON.Serialize(value));
                await _distributedCache.SetAsync(key, result, options);
            }
            catch (Exception) { }
        }
    }
}
